// Copyright 2019 Google LLC.
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#ifndef stringslice_DEFINED
#define stringslice_DEFINED

#include "modules/skplaintexteditor/include/stringview.h"

#include <memory>
#include <cstddef>

namespace SkPlainTextEditor {
// A lightweight modifiable string class.
class StringSlice {
public:
    StringSlice() = default;
    StringSlice(const char *s, std::size_t l)
    {
        this->insert(0, s, l);
    }
    StringSlice(StringSlice &&);
    StringSlice(const StringSlice &that) : StringSlice(that.begin(), that.size()) {}
    ~StringSlice() = default;
    StringSlice &operator = (StringSlice &&);
    StringSlice &operator = (const StringSlice &);

    // access:
    // Does not have a c_str method; is *not* NUL-terminated.
    const char *begin() const
    {
        return fPtr.get();
    }
    const char *end() const
    {
        return fPtr ? fPtr.get() + fLength : nullptr;
    }
    std::size_t size() const
    {
        return fLength;
    }
    SkPlainTextEditor::StringView view() const
    {
        return { fPtr.get(), fLength };
    }

    // mutation:
    void insert(std::size_t offset, const char *text, std::size_t length);
    void remove(std::size_t offset, std::size_t length);

    // modify capacity only:
    void reserve(std::size_t size)
    {
        if (size > fCapacity) {
            this->realloc(size);
        }
    }
    void shrink()
    {
        this->realloc(fLength);
    }

private:
    struct FreeWrapper {
        void operator () (void *);
    };
    std::unique_ptr<char[], FreeWrapper> fPtr;
    std::size_t fLength = 0;
    std::size_t fCapacity = 0;
    void realloc(std::size_t);
};
} // namespace SkPlainTextEditor
#endif // stringslice_DEFINED
